#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :main.py
# @Time      :2021/04/06 14:20:37
# @Author    :Raink
# 05


import requests
from coronavirus.models import City, Date
from pydantic import HttpUrl
from fastapi import BackgroundTasks
from typing import List
from fastapi import Request, APIRouter, Depends, HTTPException, applications, status
from sqlalchemy.orm import Session

from fastapi.templating import Jinja2Templates
from coronavirus import crud, schemas
from coronavirus.database import engine, Base, SessionLocal
from coronavirus.models import City, Data


applications = APIRouter()

templates = Jinja2Templates(directory='./coronavirus/templates')

Base.metadata.create_all(bind=engine)


def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


@applications.post("/create_city", response_model=schemas.ReadCity)
async def create_city(city: schemas.CreateCity, db: Session = Depends(get_db)):
    db_city = crud.get_city_by_name(db=db, name=city.province)
    if db_city:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="City is already registed"
        )
    return crud.create_city(db=db, city=city)


@applications.post("/create_data", response_model=schemas.ReadData)
async def create_data_for_city(city: str, data: schemas.CreateData, db: Session = Depends(get_db)):
    db_city = crud.get_city_by_name(db=db, name=city)
    data = crud.create_city_data(db=db, data=data, city_id=db_city.id)
    return data


@applications.get("/get_city/{city}", response_model=schemas.ReadCity)
async def get_city(city: str, db: Session = Depends(get_db)):
    db_city = crud.get_city_by_name(db=db, name=city)
    if db_city is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="City not found"
        )
    return db_city


@applications.get("/get_cities", response_model=List[schemas.ReadCity])
async def get_cities(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    cities = crud.get_cities(db=db, skip=skip, limit=limit)
    return cities


@applications.get("/get_datas", response_model=List[schemas.ReadData])
async def get_datas(city: str = None, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    data = crud.get_datas(db=db, city=city, skip=skip, limit=limit)
    return data


"""------------------------------------↓
通过Jinja2模板引擎的接口，前后端不分离
"""  # -------------------------------------

"""同步数据的后台任务"""


def bg_task(url: HttpUrl, db: Session):
    city_data = requests.get(
        url=f"{url}?source=jhu&country_code=CN&county=China&timelines=false")
    if city_data.status_code == 200:
        db.query(City).delete()
        db.query(Data).delete()
        for location in city_data.json()["locations"]:
            city = {
                "province": location["province"],
                "country": location["country"],
                "country_code": location["country_code"],
                "country_population": location["country_population"],
            }
            crud.create_city(db=db, city=schemas.CreateCity(**city))
            db_city = crud.get_city_by_name(db=db, name=location["province"])
            url=f"{url}?source=jhu&country_code=CN&province="+location["province"]+"&county=China&timelines=true"
            coronavirus_data = requests.get(url)
            if coronavirus_data.status_code == 200:
                city_datas = coronavirus_data.json()["locations"][0]["timelines"]
                for date, confirmed in city_datas["confirmed"]["timeline"].items():
                    data = {
                        "date": date.split("T")[0],
                        "confirmed": confirmed,
                        "deaths": city_datas["deaths"]["timeline"][date],
                        "recovered": "0",
                    }
                    crud.create_city_data(db=db, data=schemas.CreateData(**data), city_id=db_city.id)


@applications.get("/sync_coronavirus_data/jhu")
def sync_coronavirus_data(background_tasks: BackgroundTasks, db: Session = Depends(get_db)):
    """
    从jhu同步数据
    https://coronavirus-tracker-api.herokuapp.com/
    """
    background_tasks.add_task(
        bg_task, 
        "https://coronavirus-tracker-api.herokuapp.com/v2/locations", 
        db
    )
    return {"Message": "正在同步数据"}


@applications.get("/")
async def coronavirus(request: Request, city: str = None, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    data = crud.get_datas(db=db, city=city, skip=skip, limit=limit)
    return templates.TemplateResponse('home.html', {
        "request": request,
        "data": data,
        "sync_data_url": "/coronavirus/sync_coronavirus_data/jhu"
    })
